package org.oos.model;

import static org.oos.dao.options.OptionsMap.FINDERS.ORDER_OPTIONS;
import static org.oos.dao.options.OptionsMap.FINDERS.PAGE_OPTIONS;

import java.util.ArrayList;
import java.util.List;

import org.oos.OOS4Java;
import org.oos.atom.elements.Area;
import org.oos.atom.elements.Author;
import org.oos.atom.elements.Category;
import org.oos.atom.elements.OfferElement;
import org.oos.atom.elements.OwnedByUser;
import org.oos.atom.entries.SiteEntry;
import org.oos.atom.entries.impl.SiteEntryImpl;
import org.oos.dao.MultimediaDao;
import org.oos.dao.ReviewDao;
import org.oos.dao.SiteCheckinDao;
import org.oos.dao.exceptions.ReadException;
import org.oos.dao.options.OrderOptions.Criteria;
import org.oos.lists.CheckinList;
import org.oos.lists.MediaList;
import org.oos.lists.MultimediaList;
import org.oos.lists.ReviewList;
import org.oos.util.Log;

/**
 * 11870 service as returned from a search.
 * 
 * 
 * Description of what fields are needed for {@link AbstractEntityImpl} are
 * found at: com.oos.api.abdera.EntryWrapper@toEntry(Entry, [SearchedGeo |
 * SearchedSitio])
 * 
 * TODO: Commenting
 */
public class Site extends AbstractEntityImpl {
	private static final long serialVersionUID = -1562641528513402169L;

	private SiteEntry entry;

	public Site(OOS4Java oos4Java, SiteEntry entry) {
		super(oos4Java);
		this.entry = entry;
	}

	public Site(OOS4Java oos4Java, String name, String address,
			String locality, String country) {
		super(oos4Java);
		this.entry = new SiteEntryImpl();
		this.entry.setName(name);

		SiteLocation location = new SiteLocation();
		location.setAddress(address);
		location.setLocality(Area.create(locality, ""));
		location.setCountry(Area.create("", '/' + country.toLowerCase()));
		this.entry.setLocation(location);
	}

	public Site(OOS4Java oos4Java, String name, String address,
			String locality, String country, String phone, String url) {
		this(oos4Java, name, address, locality, country);
		this.entry.setPhone(phone);
		this.entry.setUrl(url);
	}

	public SiteEntry getEntry() {
		return entry;
	}

	public void setEntry(SiteEntry entry) {
		this.entry = entry;
	}

	public Integer getOosId() {
		return entry.getOosId();
	}

	public String getSlug() {
		return entry.getSlug();
	}

	public String getName() {
		return entry.getName();
	}

	public String getPhone() {
		return entry.getPhone();
	}

	public String getUrl() {
		return entry.getUrl();
	}

	public SiteLocation getLocation() {
		if (entry != null) {
			return entry.getLocation();
		}
		return null;
	}

	public Integer getReviewCount() {
		return entry.getReviewCount();
	}

	public Integer getSaveCount() {
		return entry.getSaveCount();
	}

	public List<OosImage> getImages() {
		return entry.getImages();
	}

	public List<String> getTags() {
		List<String> tags = new ArrayList<String>();
		for (Category category : entry.getTags()) {
			tags.add(category.getTerm());
		}
		return tags;
	}

	public List<String> getCategories() {
		List<String> cats = new ArrayList<String>();
		for (Category category : entry.getTags()) {
			cats.add(category.getLabel());
		}
		return cats;
	}

	public List<String> getAttributes() {
		List<String> attrs = new ArrayList<String>();
		for (Category category : entry.getTags()) {
			attrs.add(category.getLabel());
		}
		return attrs;
	}

	public String getSnippet() {
		return entry.getSummary().getValue();
	}

	public Integer getRating() {
		if (entry.getRating() != null) {
			return entry.getRating().getValue();
		} else {
			return 0;
		}
	}

	public boolean isOwnedByUser() {
		return entry.getOwnedByUser() != null;
	}

	public void setOwnedByUser(boolean owned) {
		if (owned) {
			entry.setOwnedByUser(new OwnedByUser());
		} else {
			entry.setOwnedByUser(null);
		}
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Site) {
			Site other = (Site) obj;
			if (other.entry.getSlug().equals(entry.getSlug())) {
				return true;
			}
		}
		return false;
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(getName());
		return sb.toString();
	}

	public List<Author> getSavedBy() {
		if (entry.getSavedBy() != null) {
			return new ArrayList<Author>(entry.getSavedBy().getUsers());
		} else {
			return new ArrayList<Author>();
		}
	}

	public List<Review> getReviews() throws ReadException {
		return getReviews(Criteria.CONTENT);
	}

	public List<Review> getReviews(Criteria criteria) throws ReadException {
		ReviewDao dao = oos4Java.getReviewDao();
		ORDER_OPTIONS.get(dao.getOptions()).setOrder(criteria);
		dao.setSiteSlug(getSlug());
		return new ReviewList(oos4Java, dao.read());
	}
	
	public List<Multimedia> getMultimedia() throws ReadException {
		return getMultimedia(-1);
	}
	
	public List<Multimedia> getMultimedia(int pageSize) throws ReadException {
		MultimediaDao dao = oos4Java.getMultimediaDao();
		dao.setSiteSlug(getSlug());
		if (pageSize > 0) {
			PAGE_OPTIONS.get(dao.getOptions()).setPageSize(pageSize);
		}
		return new MultimediaList(oos4Java, dao.read(), this);
	}
	
	public List<OosMedia> getImagesList() throws ReadException {
		return getImagesList(-1);
	}
	
	public List<OosMedia> getImagesList(int pageSize) throws ReadException {
		MultimediaDao dao = oos4Java.getMultimediaDao();
		dao.setSiteSlug(getSlug());
		if (pageSize > 0) {
			PAGE_OPTIONS.get(dao.getOptions()).setPageSize(pageSize);
		}
		return new MediaList(oos4Java, dao.read(), this);
	}
	
	

	public List<Checkin> getCheckins() {
		try {
			SiteCheckinDao dao = oos4Java.getSiteCheckinDao();
			dao.setSiteSlug(getSlug());
			return new CheckinList(oos4Java, dao.read());
		} catch (ReadException e) {
			Log.e(e);
		}
		return new ArrayList<Checkin>();
	}
	
	public Offer getOffer() {
		Offer offer = null;
		OfferElement element = entry.getOffer();
		if (element != null) {
			offer = new Offer(oos4Java, element);
		}
		return offer;
	}
	
}
